home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / monthtool < prev    next >
Encoding:
Internet Message Format  |  1987-10-03  |  49.9 KB

  1. Subject:  v11i090:  Sunview visual calendar
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: Sarah Metcalfe <cognos!sarahm>
  7. Posting-number: Volume 11, Issue 90
  8. Archive-name: monthtool
  9.  
  10. [  To get this to work I had to #ifdef-out the TEXTSW_EDIT_COUNT stuff.
  11.    Also, the Makefile is a little funky; don't do make clean.  --r$  ]
  12.  
  13.  
  14. #!/bin/sh
  15. # This is a shell archive, meaning:
  16. # 1. Remove everything above the #!/bin/sh line.
  17. # 2. Save the resulting text in a file.
  18. # 3. Execute the file with /bin/sh (not csh) to create the files:
  19. #    README
  20. #    Makefile
  21. #    monthtool.1
  22. #    monthtool.c
  23. #    monthtool.font.uu
  24. #    monthtool.h
  25. export PATH; PATH=/bin:$PATH
  26. if test -f 'README'
  27. then
  28.     echo shar: over-writing existing file "'README'"
  29. fi
  30. cat << \SHAR_EOF > 'README'
  31.  
  32. Monthtool is a visual direct manipulation "month-at-a-glance"
  33. type  calendar  and  reminder  system  using Sunview.  It is
  34. based on work done by Mike Essex on the vcal group  of  pro-
  35. grams.  Some ideas on setting up the interface were borrowed
  36. from the calctool program by Rich Burridge.
  37.  
  38. This program works on Sun  3  systems  only.    To  install:
  39. check  the  Makefile  and change the INSTALLDIR, MANDIR, and
  40. SRCDIR Make macros to the following directories, respective-
  41. ly:  the  directory  where Monthtool is to be installed, the
  42. directory where the man page is to  go,  and  the  directory
  43. where  the  source  and  the specialized font are to remain.
  44. Then, simply do  a  "make  install",  followed  by  a  "make
  45. clean", if required.
  46.  
  47. I hope it turns out to  be  useful.   Improvements  and  bug
  48. fixes most welcome.
  49.  
  50.  
  51.                                         Regards, 
  52.                                            Sarah Metcalfe
  53.  
  54. ______
  55. Sarah Metcalfe         decvax!utzoo!dciem!nrcaer!cognos!sarahm
  56. Cognos Incorporated    3755 Riverside Drive, Ottawa, Ontario, CANADA  K1G 3N3
  57.                        (613) 738-1440
  58. SHAR_EOF
  59. if test -f 'Makefile'
  60. then
  61.     echo shar: over-writing existing file "'Makefile'"
  62. fi
  63. cat << \SHAR_EOF > 'Makefile'
  64. SRCDIR        = /system/util/monthtool
  65. INSTALLDIR    = /usr/local/bin
  66. MANDIR        = /usr/local/man/man1
  67. LIBS          = -lm -lsuntool -lsunwindow -lpixrect
  68. CFLAGS        = -O
  69. PROG          = monthtool 
  70. MAN           = monthtool.1
  71.  
  72. monthtool:      monthtool.font monthtool.o
  73.                         cc -o $(PROG) monthtool.o $(LIBS)
  74.  
  75. monthtool.o:    monthtool.c monthtool.h 
  76.                         cc $(CFLAGS) -DFONTDIR="\"$(SRCDIR)\"" -c monthtool.c
  77.  
  78. monthtool.font: monthtool.font.uu 
  79.                         uudecode monthtool.font.uu
  80.  
  81. install:        $(PROG) $(MAN)
  82.                         install -s -m 555 $(PROG) $(INSTALLDIR)
  83.                         install -c -m 644 monthtool.1 $(MANDIR)
  84.  
  85. clean:    
  86.                         rm -f monthtool.o $(PROG) core monthtool.font.uu
  87. SHAR_EOF
  88. if test -f 'monthtool.1'
  89. then
  90.     echo shar: over-writing existing file "'monthtool.1'"
  91. fi
  92. cat << \SHAR_EOF > 'monthtool.1'
  93. .TH MONTHTOOL 1L 
  94. .SH NAME
  95. monthtool \- a mouse-oriented direct manipulation calendar and 
  96. reminder organizer
  97. .SH SYNOPSIS
  98. .B monthtool
  99. .SH DESCRIPTION
  100. .sp
  101. .TP
  102. .B Overview
  103. .br
  104. .sp
  105. \fIMonthtool\fR
  106. displays a Suntools-oriented calendar of any month of any year and
  107. allows the user to browse the days of that month, and
  108. to schedule and recall reminders for that day.
  109. .br
  110. .TP
  111. .B Windows
  112. .sp
  113. Month Name Window:
  114. .br
  115. The name and year of the displayed calendar is indicated.
  116. Two arrow buttons allow the user to move to other months (up arrow moves
  117. to the previous month, down arrow to the following month).  A button
  118. labelled "Today" moves the calendar to the current month of the current
  119. year, highlights today's date in the calendar, and displays today's reminders.
  120. .sp
  121. Dates Window:
  122. .br
  123. The days of the month are shown in calendar format.  
  124. When the user clicks on a date in this window, that date is highlighted
  125. and the reminders for that particular day are shown in the Reminder Window.
  126. Days that have (most types of) reminders associated with them have a bolder
  127. border.
  128. .sp
  129. Reminder Type Buttons Window:
  130. .br
  131. Four push-buttons indicating the types of reminders are shown.
  132. Clicking on one type will set the reminder that currently has
  133. the insertion caret on it (in the Reminder Window) to that type. 
  134. .sp
  135. Reminder Window: 
  136. .br
  137. Reminders for the currently highlighted date are shown.  Indicators
  138. of the type of each reminder are indicated at the beginning of each
  139. reminder line.  Reminders may be added, deleted or modified, using the
  140. standard 
  141. \fItextedit\fR 
  142. features.  A type may be set by positioning the insertion
  143. caret on the reminder and clicking on the required type in the
  144. Reminder Type Buttons Window.
  145. .br
  146. .TP
  147. .B Reminder Types
  148. .br
  149. .sp
  150. Reminders may be one of four types:
  151. .sp
  152. This day only reminders:
  153. .br
  154. These reminders are one time only events, such as appointments. 
  155. A reminder of this type has a black box at the front of the message.
  156. When one of these is associated with a given day, the border of that
  157. date in the calendar will be made bolder, as an indicator.
  158. .sp
  159. Yearly reminders:
  160. .br
  161. Reminders that happen once a year, such as birthdays. 
  162. A reminder of this type has a hollow box containing a "Y" at the 
  163. front of the message.
  164. When one of these is associated with a given month and day, the border of that
  165. date in the calendar will be made bolder, as an indicator.
  166. .sp
  167. Monthly reminders:
  168. .br
  169. Reminders that happen once a month, such as loan payments. 
  170. A reminder of this type has a hollow box containing a "M" at the 
  171. front of the message.
  172. When one of these is associated with a given date, the border of that
  173. date in the calendar will be made bolder, as an indicator.
  174. .sp
  175. Daily reminders:
  176. .br
  177. Constant reminders, things to remember to do. 
  178. A reminder of this type has a hollow box containing a "D" at the 
  179. front of the message.
  180. .sp
  181. .TP
  182. .B Menu Commands
  183. .sp
  184. Available with the right mouse button, except when in the Reminders Window
  185. (when the standard 
  186. \fItextedit\fR 
  187. menu is available).
  188. .sp
  189. Close with Save:
  190. .br
  191. Close the window to the icon and save the reminders in the .monthtool file.
  192. .sp
  193. Save:
  194. .br
  195. Save the reminders in the .monthtool file.
  196. .sp
  197. Reload:
  198. .br
  199. Reload the reminders from the last version of the .monthtool file.
  200. .sp
  201. Quit with Save:
  202. .br
  203. Save the reminders in the .monthtool file and quit.
  204. .sp
  205. Note that the standard frame menu (available when in the borders of any window)
  206. allows the user to quit and close without saving.  Resize, Redisplay, etc.
  207. are also available, as is usually the case.
  208. .br
  209. .TP
  210. .B The .monthtool File
  211. .br
  212. .sp
  213. The reminders are kept in a file in the home directory called the .monthtool 
  214. file.   This file is kept in a format similar to that used by 
  215. \fIautocall\fR, used
  216. to warn the user of impending appointments.  If this feature is required,
  217. the time for the appointments must be the first token of the message
  218. (after the type indicator) and must be in the format hh:mm or h:mm, 24-hour
  219. time.
  220. .sp
  221. Each reminder is a line (of length 80 characters or less) in the .monthtool
  222. file in 
  223. the following format:
  224. .sp
  225. .ta +1i 
  226. m,d,y,tttt,s
  227. .ta -1i
  228. .sp
  229. where m is the one or two digit month number, d is the one or two digit date, y
  230. is the year (up to 4 digits), tttt is either 4 blanks (if no time is required)
  231. or 24 time in hhmm format, and s is the reminder message.   
  232. For yearly reminders, the
  233. y field is 0 (zero); for monthly reminders, the
  234. m field and the y field are 0 (zero); for daily reminders, the d field, the
  235. m field, and the y field are 0 (zero).
  236. .SH AUTHORS
  237. .ta +1.15i
  238. Sarah Metcalfe
  239. .br
  240. Mike Essex
  241. .br
  242. Rich Burridge
  243. .SH FILES
  244. $HOME/.monthtool
  245. .SH SEE ALSO
  246. \fIvcal\fR(1), \fIautocall\fR(1), \fItextedit\fR(1), \fIsuntools\fR(1)
  247. .LP
  248. \fI"Windows and Window-Based Tools: Beginner's Guide"\fR
  249. .SH DIAGNOSTICS
  250. Monthtool warning! Invalid record: \fIrecord\fR 
  251. .br
  252. Monthtool error:  Cannot open \fI~/.monthtool\fR file
  253. .SH BUGS
  254. Although the .monthtool file has a similar format to
  255. the .appointments file of \fIvcal\fR, 
  256. \fIvcal\fR cannot support the yearly, monthly, or daily reminders.  If vcal
  257. is used on the file, reminders of that type will be lost.
  258. .SH DATE
  259. 24/6/87
  260. SHAR_EOF
  261. if test -f 'monthtool.c'
  262. then
  263.     echo shar: over-writing existing file "'monthtool.c'"
  264. fi
  265. cat << \SHAR_EOF > 'monthtool.c'
  266.  
  267. /*
  268.     Name:        monthtool
  269.   
  270.     Purpose:     visual appointment calendar 
  271.   
  272.     Author:        Sarah Metcalfe apres Mike Essex & Rich Burridge
  273.   
  274.     Date:        June 24, 1987 
  275.   
  276.     Discussion: Displays a calendar to the screen for a given month.  
  277.                 User may move the mouse to any day of the
  278.                 month and view or enter appointments for that date. 
  279. */
  280.  
  281.  
  282.  
  283.  
  284. #include "monthtool.h"
  285.  
  286. void             dateEvent();
  287.  
  288. void             monthEvent();
  289. void             todayBtnHit();
  290. void             upBtnHit();
  291. void             downBtnHit();
  292. void             monthBackgroundHit();
  293.  
  294. void             notesBackgroundHit();
  295. void             notesPanelEvent();
  296. void             notesRadioHit();
  297.  
  298. Canvas             datesDsply;
  299. Textsw             notesDsply;
  300. Panel             monthPanel,
  301.                  notesPanel;
  302. Frame             frame;
  303. Menu             mainMenu,
  304.                  fileMenu;
  305. Panel_item         monthItem,
  306.                  notesTypeItem;
  307. Pixwin            *datesCrayon;
  308. struct pixfont     *font,
  309.                 *notesFont;
  310.  
  311.  
  312. short             dayIcon[] = {
  313.     0xFFFF,0xFFFF,0xFF00,0x0000,0x8000,0x0000,0x0100,0x0000,
  314.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  315.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  316.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  317.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  318.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  319.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  320.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  321.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  322.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  323.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  324.     0x8000,0x0000,0x0100,0x0000,0x8000,0x0000,0x0100,0x0000,
  325.     0x8000,0x0000,0x0100,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  326.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  327.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  328.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  329.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  330.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  331.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  332.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  333.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  334.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  335.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  336.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  337.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  338.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  339.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  340.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  341.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  342.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  343.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  344.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
  345. };
  346. mpr_static(dayPr, 64, 64, 1, dayIcon);
  347.  
  348. short             bigDayIcon[] = {
  349.     0xFFFF,0xFFFF,0xFF00,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  350.     0xFFFF,0xFFFF,0xFF00,0x0000,0xE000,0x0000,0x0700,0x0000,
  351.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  352.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  353.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  354.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  355.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  356.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  357.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  358.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  359.     0xE000,0x0000,0x0700,0x0000,0xE000,0x0000,0x0700,0x0000,
  360.     0xE000,0x0000,0x0700,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  361.     0xFFFF,0xFFFF,0xFF00,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  362.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  363.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  364.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  365.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  366.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  367.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  368.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  369.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  370.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  371.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  372.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  373.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  374.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  375.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  376.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  377.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  378.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  379.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  380.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
  381. };
  382. mpr_static(bigDayPr, 64, 64, 1, bigDayIcon);
  383.  
  384. short             daySelIcon[] = {
  385.     0xFFFF,0xFFFF,0xFF00,0x0000,0xA222,0x2222,0x2300,0x0000,
  386.     0xC444,0x4444,0x4500,0x0000,0x9111,0x1111,0x1100,0x0000,
  387.     0x8888,0x8888,0x8900,0x0000,0xA222,0x2222,0x2300,0x0000,
  388.     0xC444,0x4444,0x4500,0x0000,0x9111,0x1111,0x1100,0x0000,
  389.     0x8888,0x8888,0x8900,0x0000,0xA222,0x2222,0x2300,0x0000,
  390.     0xC444,0x4444,0x4500,0x0000,0x9111,0x1111,0x1100,0x0000,
  391.     0x8888,0x8888,0x8900,0x0000,0xA222,0x2222,0x2300,0x0000,
  392.     0xC444,0x4444,0x4500,0x0000,0x9111,0x1111,0x1100,0x0000,
  393.     0x8888,0x8888,0x8900,0x0000,0xA222,0x2222,0x2300,0x0000,
  394.     0xC444,0x4444,0x4500,0x0000,0x9111,0x1111,0x1100,0x0000,
  395.     0x8888,0x8888,0x8900,0x0000,0xA222,0x2222,0x2300,0x0000,
  396.     0xC444,0x4444,0x4500,0x0000,0x9111,0x1111,0x1100,0x0000,
  397.     0x8888,0x8888,0x8900,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  398.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  399.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  400.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  401.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  402.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  403.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  404.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  405.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  406.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  407.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  408.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  409.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  410.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  411.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  412.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  413.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  414.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  415.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  416.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
  417. };
  418. mpr_static(daySelPr, 64, 64, 1, daySelIcon);
  419.  
  420. short             bigDaySelIcon[] = {
  421.     0xFFFF,0xFFFF,0xFF00,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  422.     0xFFFF,0xFFFF,0xFF00,0x0000,0xF111,0x1111,0x1700,0x0000,
  423.     0xE888,0x8888,0x8F00,0x0000,0xE222,0x2222,0x2700,0x0000,
  424.     0xE444,0x4444,0x4700,0x0000,0xF111,0x1111,0x1700,0x0000,
  425.     0xE888,0x8888,0x8F00,0x0000,0xE222,0x2222,0x2700,0x0000,
  426.     0xE444,0x4444,0x4700,0x0000,0xF111,0x1111,0x1700,0x0000,
  427.     0xE888,0x8888,0x8F00,0x0000,0xE222,0x2222,0x2700,0x0000,
  428.     0xE444,0x4444,0x4700,0x0000,0xF111,0x1111,0x1700,0x0000,
  429.     0xE888,0x8888,0x8F00,0x0000,0xE222,0x2222,0x2700,0x0000,
  430.     0xE444,0x4444,0x4700,0x0000,0xF111,0x1111,0x1700,0x0000,
  431.     0xE888,0x8888,0x8F00,0x0000,0xE222,0x2222,0x2700,0x0000,
  432.     0xE444,0x4444,0x4700,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  433.     0xFFFF,0xFFFF,0xFF00,0x0000,0xFFFF,0xFFFF,0xFF00,0x0000,
  434.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  435.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  436.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  437.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  438.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  439.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  440.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  441.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  442.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  443.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  444.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  445.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  446.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  447.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  448.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  449.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  450.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  451.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  452.     0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
  453. };
  454. mpr_static(bigDaySelPr, 64, 64, 1, bigDaySelIcon);
  455.  
  456.  
  457. short             upBtnIcon[] = {
  458.     0x3FFF,0xE000,0x7FFF,0xF000,
  459.     0xE000,0x3800,0xC000,0x1800,
  460.     0xC020,0x1800,0xC070,0x1800,
  461.     0xC0F8,0x1800,0xC1FC,0x1800,
  462.     0xC3FE,0x1800,0xC7FF,0x1800,
  463.     0xCFFF,0x9800,0xC0F8,0x1800,
  464.     0xC0F8,0x1800,0xC0F8,0x1800,
  465.     0xC0F8,0x1800,0xC000,0x1800,
  466.     0xE000,0x3800,0x7FFF,0xF000,
  467.     0x3FFF,0xE000,0x0000,0x0000
  468. };
  469. mpr_static(upBtnPr, BTN_WIDTH, BTN_HEIGHT, 1, upBtnIcon);
  470.  
  471. short             downBtnIcon[] = {
  472.     0x3FFF,0xE000,0x7FFF,0xF000,
  473.     0xE000,0x3800,0xC000,0x1800,
  474.     0xC0F8,0x1800,0xC0F8,0x1800,
  475.     0xC0F8,0x1800,0xC0F8,0x1800,
  476.     0xCFFF,0x9800,0xC7FF,0x1800,
  477.     0xC3FE,0x1800,0xC1FC,0x1800,
  478.     0xC0F8,0x1800,0xC070,0x1800,
  479.     0xC020,0x1800,0xC000,0x1800,
  480.     0xE000,0x3800,0x7FFF,0xF000,
  481.     0x3FFF,0xE000,0x0000,0x0000
  482. };
  483. mpr_static(downBtnPr, BTN_WIDTH, BTN_HEIGHT, 1, downBtnIcon);
  484.  
  485.  
  486. short             toolIcon[] = {
  487.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8C08,0x87C2,0x21F0,0xF031,
  488.     0x920D,0x8102,0x2040,0x8049,0x880A,0x8102,0xA040,0xE021,
  489.     0x840A,0x8102,0xA040,0x8011,0x9208,0x8103,0x6040,0x8049,
  490.     0x8C08,0x8102,0x2040,0x8031,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
  491.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8040,0x2010,0x0804,0x0201,
  492.     0x8040,0x2814,0x0A05,0x0281,0x8040,0x2814,0x0A05,0x0281,
  493.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0804,0x0201,
  494.     0x8040,0x2013,0xA804,0x0201,0x8040,0x2010,0x0804,0x0201,
  495.     0x8040,0x2016,0x8804,0x0201,0x8040,0x2010,0x0804,0x0201,
  496.     0x8040,0x2010,0x0804,0x0201,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
  497.     0x8040,0x2010,0x0804,0x0201,0xA050,0x2814,0x0B05,0x82C1,
  498.     0xA050,0x2814,0x0B05,0x82C1,0x8040,0x2010,0x0804,0x0201,
  499.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0805,0xD201,
  500.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0804,0x0201,
  501.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0804,0x0201,
  502.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8040,0x2010,0x0804,0x0201,
  503.     0xB058,0x2C16,0x0B05,0x82C1,0xB058,0x2C16,0x0B05,0x82C1,
  504.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2F50,0x0804,0x0201,
  505.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2D50,0x0804,0x0201,
  506.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0804,0x0201,
  507.     0x8040,0x2010,0x0804,0x0201,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
  508.     0x8040,0x2010,0x0804,0x0201,0xB058,0x2C16,0x0B05,0x82C1,
  509.     0xB058,0x2C16,0x0B05,0x82C1,0x8040,0x2010,0x0804,0x0201,
  510.     0x8040,0x2010,0x0BE4,0x0201,0x8040,0x2010,0x0804,0x0201,
  511.     0x8040,0x2010,0x0BA4,0x0201,0x8040,0x2010,0x0804,0x0201,
  512.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0804,0x0201,
  513.     0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8040,0x2010,0x0804,0x0201,
  514.     0xB058,0x2C16,0x0B04,0x0201,0xB058,0x2C16,0x0B04,0x0201,
  515.     0x8040,0x2010,0x0804,0x0201,0x8040,0x2010,0x0804,0x0201,
  516.     0xBA40,0x2017,0xC804,0x0201,0x8040,0x2010,0x0804,0x0201,
  517.     0x8040,0x2013,0xC804,0x0201,0x9240,0x2010,0x0804,0x0201,
  518.     0x8040,0x2010,0x0804,0x0201,0xFFFF,0xFFFF,0xFFFF,0xFFFF
  519. };
  520. DEFINE_ICON_FROM_IMAGE(monthIcon, toolIcon);
  521.  
  522.  
  523.  
  524. struct dateBox     monthBoxes[DATE_ROWS][DATE_COLS];
  525.  
  526.  
  527. struct apptsData     *firstApptRecord[NUM_NOTES_TYPE + 1 /*for NOTES_ERROR*/];
  528. struct apptsData     *lastApptRecord[NUM_NOTES_TYPE + 1 /*for NOTES_ERROR*/];
  529.  
  530.     
  531. int                     tmonth, tday, tyear;
  532.  
  533. int                     yearToShow, monthToShow;
  534. int                     dayToShow = 0;
  535. int                     dateNumToShow[NUM_NOTES_TYPE];
  536.  
  537. int                     editCount = 0;
  538. int                     notesModified = 0;
  539.  
  540. char                 typeChar[NUM_NOTES_TYPE] = { 0x90, 0x91, 0x92, 0x93 }; 
  541. char                 typeMark[3] = "  ";
  542.                             
  543. char                *smon[] = { "January", "February", "March",
  544.                                 "April", "May", "June",
  545.                                 "July", "August", "September",
  546.                                 "October", "November", "December"
  547.                               };
  548. int                     mon[] = { 0,     31, 29, 31, 
  549.                                     30, 31, 30,
  550.                                     31, 31, 30, 
  551.                                     31, 30, 31, 
  552.                               };
  553.  
  554. main(argc, argv)
  555.  
  556. int         argc;
  557. char    *argv[];
  558.  
  559. {
  560.     char    fontString[80];
  561.     char    choiceString[2];
  562.     int        type;
  563.  
  564.  
  565.     /* Set up menus */
  566.                         
  567.     fileMenu = menu_create(MENU_ITEM,
  568.                                 MENU_STRING,    "Save",
  569.                                 MENU_VALUE,         MENU_SAVE,
  570.                                 0,
  571.                             MENU_ITEM,
  572.                                 MENU_STRING,    "Reload",
  573.                                 MENU_VALUE,         MENU_RELOAD,
  574.                                 0,
  575.                             0);
  576.  
  577.     mainMenu = menu_create(MENU_ITEM,
  578.                                 MENU_STRING,    "Close (with Save)",
  579.                                 MENU_VALUE,         MENU_CLOSE,
  580.                                 0,
  581.                             MENU_ITEM,
  582.                                 MENU_STRING,    "Update Appts.",
  583.                                 MENU_PULLRIGHT,     fileMenu,
  584.                                 0,
  585.                             MENU_ITEM,
  586.                                 MENU_STRING,    "Quit (with Save)",
  587.                                 MENU_VALUE,         MENU_QUIT,
  588.                                 0,
  589.                             0);
  590.                         
  591.  
  592.     /*    Set up windows */
  593.  
  594.     font = pf_open(LARGEFONT);                /* Open large sized font. */
  595.     strcpy(fontString, FONTDIR);
  596.     strcat(fontString, NORMALFONT);
  597.     notesFont = pf_open(fontString);        /* Open regular sized font. */
  598.  
  599.     frame = window_create(0, FRAME,
  600.                 FRAME_ICON, &monthIcon,
  601.                 FRAME_SHOW_LABEL, FALSE,
  602.                 FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
  603.                 FRAME_NO_CONFIRM, FALSE,
  604.                 WIN_HEIGHT, DATES_HEIGHT + MONTH_HEIGHT + 
  605.                     NOTES_PANEL_HEIGHT + NOTES_HEIGHT + 25,
  606.                 WIN_WIDTH, WINDOW_WIDTH + 10,
  607.                 FRAME_ARGS, argc, argv,
  608.                 0);
  609.  
  610.     monthPanel = window_create(frame, PANEL,
  611.                 WIN_X, 0,
  612.                 WIN_Y, 0,
  613.                 WIN_HEIGHT, MONTH_HEIGHT,
  614.                 WIN_WIDTH, WINDOW_WIDTH,
  615.                 WIN_FONT, font,
  616.                 PANEL_BACKGROUND_PROC, monthBackgroundHit,
  617.                 PANEL_EVENT_PROC, monthEvent,
  618.                 0);
  619.  
  620.     datesDsply = window_create(frame, CANVAS,
  621.                 WIN_X, 0,
  622.                 WIN_BELOW, monthPanel,
  623.                 WIN_HEIGHT, DATES_HEIGHT,
  624.                 WIN_WIDTH, WINDOW_WIDTH,
  625.                 WIN_FONT, font,
  626.                 WIN_EVENT_PROC, dateEvent,
  627.                 0);
  628.     datesCrayon = canvas_pixwin(datesDsply);
  629.  
  630.     notesPanel = window_create(frame, PANEL,
  631.                 WIN_X, 0,
  632.                 WIN_BELOW, datesDsply,
  633.                 WIN_HEIGHT, NOTES_PANEL_HEIGHT,
  634.                 WIN_WIDTH, WINDOW_WIDTH,
  635.                 WIN_FONT, notesFont,
  636.                 PANEL_BACKGROUND_PROC, notesBackgroundHit,
  637.                 PANEL_EVENT_PROC, notesPanelEvent,
  638.                 0);
  639.  
  640.     notesDsply = window_create(frame, TEXTSW,
  641.                 WIN_X, 0,
  642.                 WIN_BELOW, notesPanel,
  643.                 WIN_HEIGHT, WIN_EXTEND_TO_EDGE,
  644.                 WIN_WIDTH, 10000 /* very large number, cuts to actual width */,
  645.                 WIN_FONT, notesFont,
  646.                 TEXTSW_IGNORE_LIMIT, TEXTSW_INFINITY,
  647.                 0);
  648.  
  649.     /* Set up panels */
  650.  
  651.  
  652.     monthItem = panel_create_item(monthPanel, PANEL_MESSAGE,
  653.                     PANEL_LABEL_X, 5,
  654.                     PANEL_LABEL_Y, 10,
  655.                   0);
  656.                         
  657.  
  658.     panel_create_item( monthPanel, PANEL_BUTTON,
  659.                         PANEL_ITEM_X, WINDOW_WIDTH - 2 * (BTN_WIDTH + GAP) - 55,
  660.                         PANEL_ITEM_Y, 10,
  661.                           PANEL_NOTIFY_PROC, todayBtnHit, 
  662.                            PANEL_LABEL_IMAGE,
  663.                             panel_button_image(monthPanel,"Today",0,notesFont),
  664.                         0);
  665.  
  666.     panel_create_item( monthPanel, PANEL_BUTTON,
  667.                         PANEL_ITEM_X, WINDOW_WIDTH - 2 * (BTN_WIDTH + GAP),
  668.                         PANEL_ITEM_Y, 10,
  669.                           PANEL_NOTIFY_PROC, upBtnHit, 
  670.                            PANEL_LABEL_IMAGE, &upBtnPr,
  671.                         0);
  672.  
  673.     panel_create_item( monthPanel, PANEL_BUTTON,
  674.                         PANEL_ITEM_X, WINDOW_WIDTH - (BTN_WIDTH + GAP),
  675.                         PANEL_ITEM_Y, 10,
  676.                           PANEL_NOTIFY_PROC, downBtnHit, 
  677.                            PANEL_LABEL_IMAGE, &downBtnPr,
  678.                         0);
  679.  
  680.  
  681.     notesTypeItem = panel_create_item( notesPanel, PANEL_CHOICE,
  682.                         PANEL_LABEL_STRING, "Reminder Types:",
  683.                         PANEL_FEEDBACK, PANEL_NONE,
  684.                         PANEL_NOTIFY_PROC, notesRadioHit,
  685.                     0);
  686.     choiceString[1] = '\0';
  687.     for (type = 0; type < NUM_NOTES_TYPE; type++) {
  688.         choiceString[0] = typeChar[type];
  689.         panel_set( notesTypeItem, PANEL_CHOICE_STRING, type, choiceString, 0);
  690.         panel_set( notesTypeItem, PANEL_CHOICE_X, type, 100 + 40*(type+1), 0);
  691.         panel_set( notesTypeItem, PANEL_CHOICE_Y, type, 4, 0);
  692.     }
  693.     panel_set( notesTypeItem, PANEL_LABEL_X, 4, 0);
  694.     panel_set( notesTypeItem, PANEL_LABEL_Y, 4, 0);
  695.  
  696.     /* Get today's date */
  697.  
  698.     todaySet();
  699.     yearToShow = tyear;
  700.     monthToShow = tmonth;
  701.  
  702.     /* Load the appointments file and show this month's calendar */
  703.     
  704.     loadData();    
  705.     dayHit(tday);    
  706.  
  707.     /* Wait for events */
  708.  
  709.     window_main_loop(frame);
  710.  
  711.     /* When done, leave */
  712.  
  713.     freeData();
  714.     exit(0);
  715.  
  716. }
  717.  
  718. static void    monthEvent(item, event)
  719.  
  720. Panel_item     item;
  721. Event        *event;
  722.  
  723. {
  724.     switch (event_id(event)) {
  725.     case MS_RIGHT:
  726.         if (event_is_down(event)) {
  727.             rootMenuDisplay(monthPanel,event);
  728.         }
  729.         break;
  730.     case MS_LEFT:
  731.         panel_default_handle_event(item,event);
  732.         break;
  733.     default:
  734.         return;
  735.     }
  736.  
  737. }
  738.  
  739. static void    todayBtnHit(item, event)
  740.  
  741. Panel_item     item;
  742. Event        *event;
  743.  
  744. {
  745.     todaySet();
  746.     if ( (monthToShow != tmonth) || (yearToShow != tyear) ) {
  747.         notesSave();
  748.         monthToShow = tmonth;
  749.         yearToShow = tyear;
  750.         monthDisplay();
  751.         dayHit(tday);
  752.     }else{
  753.         if (dayToShow != tday) {
  754.             notesSave();
  755.             dayHit(tday);
  756.         }
  757.     }
  758. }
  759.  
  760. static void    upBtnHit(item, event)
  761.  
  762. Panel_item     item;
  763. Event        *event;
  764.  
  765. {
  766.     notesSave();
  767.     if (--monthToShow < 1) {
  768.         monthToShow = 12;
  769.         yearToShow--;
  770.     }
  771.     monthDisplay();
  772.     dayHit(1);
  773.  
  774. }
  775.  
  776. static void    downBtnHit(item, event)
  777.  
  778. Panel_item     item;
  779. Event        *event;
  780.  
  781. {
  782.     notesSave();
  783.     if (++monthToShow == 13) {
  784.         monthToShow = 1;
  785.         yearToShow++;
  786.     }
  787.     monthDisplay();
  788.     dayHit(1);
  789.  
  790. }
  791.  
  792. static void    monthBackgroundHit(panel, event)
  793.  
  794. Panel         panel;
  795. Event        *event;
  796.  
  797. {
  798.     switch (event_id(event)) {
  799.     case MS_RIGHT:
  800.         if (event_is_down(event)) {
  801.             rootMenuDisplay(monthPanel,event);
  802.         }
  803.         break;
  804.     default:
  805.         return;
  806.     }
  807.  
  808. }
  809.  
  810. static void    dateEvent(win, event, arg)
  811.  
  812. Canvas         win;
  813. Event        *event;
  814. caddr_t         arg;
  815.  
  816. {
  817.     int            column,
  818.                 row;
  819.  
  820.     if (event_is_up(event)) {
  821.         return;
  822.     }
  823.  
  824.     switch (event_id(event)) {
  825.     case MS_LEFT:
  826.         notesSave();
  827.         column = event_x(event) / (DATE_BOX_WIDTH + GAP);
  828.         row = (event_y(event)) / (DATE_BOX_HEIGHT + GAP);
  829.         dayHit(monthBoxes[row][column].date);
  830.         break;
  831.     case MS_RIGHT:
  832.         rootMenuDisplay(win,event);
  833.         break;
  834.     case WIN_REPAINT:
  835.         notesSave();
  836.         monthDisplay();
  837.         dayHit(dayToShow);
  838.         break;
  839.     default:
  840.         return;
  841.     }
  842.  
  843. }
  844.  
  845. dayHit(date)
  846.  
  847. int    date;
  848.  
  849. {
  850.     int                     row,
  851.                          column;
  852.  
  853.     if (date != 0) {
  854.         if (dayToShow != 0) {
  855.             for (row = 0; row < DATE_ROWS; row++) {
  856.                 for (column = 0; column < DATE_COLS; column++) {
  857.                     if (dayToShow == monthBoxes[row][column].date) {
  858.                         dateBoxDisplay(row, column, NOHIGHLIGHT);
  859.                     }
  860.                 }
  861.             }
  862.         }
  863.         for (row = 0; row < DATE_ROWS; row++) {
  864.             for (column = 0; column < DATE_COLS; column++) {
  865.                 if (date == monthBoxes[row][column].date) {
  866.                     dateBoxDisplay(row, column, HIGHLIGHT);
  867.                 }
  868.             }
  869.         }
  870.  
  871.         dayToShow = date;
  872.  
  873.         dateNumToShow[NOTES_ALL_ALL_ALL] = 0;
  874.         dateNumToShow[NOTES_D_ALL_ALL] = dayToShow;
  875.         dateNumToShow[NOTES_D_M_ALL] = dayToShow + 100 * monthToShow;
  876.         dateNumToShow[NOTES_D_M_Y] = dayToShow + 100 * monthToShow + 10000 * yearToShow;
  877.  
  878.         notesDisplay();
  879.  
  880.     }
  881.  
  882. }
  883.  
  884. static void    notesPanelEvent(item, event)
  885.  
  886. Panel_item     item;
  887. Event        *event;
  888.  
  889. {
  890.  
  891.     switch (event_id(event)) {
  892.     case MS_RIGHT:
  893.         if (event_is_down(event)) {
  894.             rootMenuDisplay(notesPanel,event);
  895.         }
  896.         break;
  897.     case MS_LEFT:
  898.         panel_default_handle_event(item,event);
  899.         break;
  900.     default:
  901.         return;
  902.     }
  903.  
  904. }
  905.  
  906. static void    notesRadioHit(item, value, event)
  907.  
  908. Panel_item     item;
  909. int             value;
  910. Event        *event;
  911.  
  912. {
  913.     int            caretIndex,
  914.                 endIndex,
  915.                 lineStartIndex,
  916.                 nextLineStartIndex,
  917.                 ptrnStartIndex,
  918.                 ptrnEndIndex,
  919.                 ptrnLen,
  920.                 type,
  921.                 result,
  922.                 lineNo;
  923.  
  924.     typeMark[0] = typeChar[value];
  925.     ptrnLen = strlen(typeMark);
  926.  
  927.     caretIndex = (int)window_get( notesDsply, TEXTSW_INSERTION_POINT );
  928.  
  929.     lineNo = 0;
  930.     lineStartIndex = 0;
  931.     while (1) {
  932.         nextLineStartIndex = (int)textsw_index_for_file_line(notesDsply, lineNo+1);
  933.         if ( (nextLineStartIndex < 0) || (nextLineStartIndex > caretIndex) ) {
  934.             break;
  935.         }
  936.         lineNo++;
  937.         lineStartIndex = nextLineStartIndex;
  938.     }
  939.  
  940.     window_set( notesDsply, TEXTSW_INSERTION_POINT, lineStartIndex, 0 );
  941.     textsw_insert( notesDsply, typeMark, ptrnLen );
  942.     caretIndex += ptrnLen;
  943.  
  944.     endIndex = (int)window_get( notesDsply, TEXTSW_LENGTH );
  945.     if ( (nextLineStartIndex < 0) || (nextLineStartIndex > endIndex) ) {
  946.         nextLineStartIndex = endIndex + 1;
  947.     }
  948.     
  949.     lineStartIndex += strlen(typeMark);
  950.     for (type = 0; type < NUM_NOTES_TYPE; type++) {
  951.  
  952.         typeMark[0] = typeChar[type];
  953.         ptrnLen = strlen(typeMark);
  954.         while ( ptrnLen ) {
  955.             do {
  956.                 ptrnStartIndex = lineStartIndex;
  957.                 result = textsw_find_bytes(notesDsply, &ptrnStartIndex, &ptrnEndIndex,
  958.                     typeMark, ptrnLen, 0);
  959.                 if (result != -1) {
  960.                     if ((ptrnEndIndex < nextLineStartIndex) && (ptrnStartIndex >= lineStartIndex)) {
  961.                         textsw_erase(notesDsply, ptrnStartIndex, ptrnEndIndex);
  962.                         caretIndex -= ptrnLen;
  963.                     }else{
  964.                         result = -1;
  965.                     }
  966.                 }
  967.             } while (result != -1);
  968.             ptrnLen--;
  969.         }
  970.             
  971.     }
  972.  
  973.     window_set( notesDsply, TEXTSW_INSERTION_POINT, caretIndex, 0);
  974.  
  975. }
  976.  
  977. static void    notesBackgroundHit(panel, event)
  978.  
  979. Panel         panel;
  980. Event        *event;
  981.  
  982. {
  983.     switch (event_id(event)) {
  984.     case MS_RIGHT:
  985.         if (event_is_down(event)) {
  986.             rootMenuDisplay(notesPanel,event);
  987.         }
  988.         break;
  989.     default:
  990.         return;
  991.     }
  992.  
  993. }
  994.  
  995. rootMenuDisplay(window, event)
  996.  
  997. Window         window;
  998. Event        *event;
  999.  
  1000. {
  1001.  
  1002.     switch( (int)menu_show(mainMenu, window, event, 0) ) {
  1003.     case MENU_SAVE:
  1004.         saveData();
  1005.         break;
  1006.     case MENU_RELOAD:
  1007.         loadData();
  1008.         monthDisplay();
  1009.         dayHit(dayToShow);
  1010.         break;
  1011.     case MENU_CLOSE:
  1012.         saveData();
  1013.         window_set(frame, FRAME_CLOSED, TRUE, 0);
  1014.         break;
  1015.     case MENU_QUIT:
  1016.         saveData();
  1017.         window_destroy(frame);
  1018.         break;
  1019.     }
  1020.  
  1021. }
  1022.  
  1023. monthDisplay()
  1024.  
  1025.  
  1026. {                
  1027.     int                     column,
  1028.                          row;
  1029.     int                     i, day, dow;
  1030.     char                 monthString[20];
  1031.     struct apptsData     *cur ;
  1032.  
  1033.     sprintf(monthString, "%s %4u", smon[monthToShow-1], yearToShow);
  1034.     panel_set(monthItem, PANEL_LABEL_STRING, monthString, 0);
  1035.  
  1036.     dow = jan1Set(yearToShow);
  1037.     mon[2] = 29;
  1038.     mon[9] = 30;
  1039.     switch ((jan1Set(yearToShow + 1) + 7 - dow) % 7) {
  1040.     case 1:                /* non-leap year */
  1041.         mon[2] = 28;
  1042.         break;
  1043.     case 2:                /* leap year */
  1044.         break;
  1045.     default:            /* 1752 */
  1046.         mon[9] = 19;
  1047.         break;
  1048.     }
  1049.     for (i = 1; i < monthToShow; i++) {    
  1050.         dow += mon[i];
  1051.     }
  1052.     dow %= 7;
  1053.  
  1054.     row = 0;
  1055.     for (column = 0; column < dow; column++) {
  1056.         monthBoxes[row][column].date = 0;
  1057.         monthBoxes[row][column].hasNotes = 0;
  1058.     }
  1059.  
  1060.     for ( day = 1; day <= mon[monthToShow]; day++) {
  1061.         monthBoxes[row][column].date = day;
  1062.         monthBoxes[row][column].hasNotes = 0;
  1063.         if (column >= (DATE_COLS-1)) {
  1064.             row++;
  1065.             column = 0;
  1066.         }else{
  1067.             column++;
  1068.         }
  1069.     }
  1070.  
  1071.     for (; row < DATE_ROWS; row++) {
  1072.         for (; column < DATE_COLS; column++) {
  1073.             monthBoxes[row][column].date = 0;
  1074.             monthBoxes[row][column].hasNotes = 0;
  1075.         }
  1076.         column = 0;        
  1077.     }
  1078.  
  1079.     for (i = 0; i < NUM_NOTES_TYPE; i++) {
  1080.         if  ( i != NOTES_ALL_ALL_ALL ) {  
  1081.             for (cur = firstApptRecord[i]; cur != NULL; cur = cur->next) {
  1082.                 if (    i==NOTES_D_ALL_ALL ||
  1083.                 (             cur->month==monthToShow &&  
  1084.                 (                 i==NOTES_D_M_ALL ||
  1085.                 (                     cur->year==yearToShow 
  1086.                 )))) {  
  1087.                     monthBoxes[(cur->day + dow-1) / DATE_COLS]
  1088.                                [(cur->day + dow-1) % DATE_COLS].hasNotes = 1;
  1089.                 }
  1090.             }
  1091.         }
  1092.     }
  1093.  
  1094.     pw_writebackground(datesCrayon, 0, 0, WINDOW_WIDTH, DATES_HEIGHT, PIX_CLR);
  1095.  
  1096.     for (row = 0; row < DATE_ROWS; row++) {
  1097.         for (column = 0; column < DATE_COLS; column++) {
  1098.             dateBoxDisplay(row, column, NOHIGHLIGHT);
  1099.         }
  1100.     }
  1101.  
  1102. }
  1103.  
  1104. jan1Set(year)
  1105.  
  1106. int             year;
  1107.  
  1108. {
  1109.  
  1110.     register        y, dow;
  1111.  
  1112.     /* normal gregorian calendar one extra day per four years */
  1113.  
  1114.     y = year;
  1115.     dow = 4 + y + (y + 3) / 4;
  1116.  
  1117.     /* julian calendar regular gregorian less three days per 400 */
  1118.  
  1119.     if (y > 1800) {
  1120.         dow -= (y - 1701) / 100;
  1121.         dow += (y - 1601) / 400;
  1122.     }
  1123.  
  1124.     /* great calendar changeover instant */
  1125.  
  1126.     if (y > 1752)
  1127.         dow += 3;
  1128.  
  1129.     return (dow % 7);
  1130.  
  1131.  
  1132. todaySet()
  1133.  
  1134.  
  1135. {
  1136.     struct tm      *tp;        /* time structure */
  1137.     long            tloc;    /* number of seconds since 1970 */
  1138.  
  1139.     time(&tloc);        
  1140.     tp = localtime(&tloc);
  1141.     tyear = tp->tm_year;
  1142.     tmonth = tp->tm_mon + 1;
  1143.     tday = tp->tm_mday;
  1144.     tyear += 1900;
  1145.  
  1146. }
  1147.  
  1148. dateBoxDisplay(row, column, hilite)
  1149.  
  1150. int              row;
  1151. int              column;
  1152. int              hilite;
  1153.  
  1154. {
  1155.     char            dateString[4];
  1156.  
  1157.     if (monthBoxes[row][column].date == 0) {
  1158.         pw_write(datesCrayon, 
  1159.             column * DATE_BOX_WIDTH + DATE_BORDER + (column * GAP),
  1160.             row * DATE_BOX_HEIGHT + DATE_BORDER + (row * GAP),
  1161.             DATE_BOX_WIDTH, DATE_BOX_HEIGHT, PIX_SRC, &dayPr, 0, 0);
  1162.         pw_text(datesCrayon, 
  1163.             column * DATE_BOX_WIDTH + DATE_BORDER + (column * GAP) + 8,
  1164.             row * DATE_BOX_HEIGHT + DATE_BORDER + (row * GAP) + 20,
  1165.             PIX_SRC | PIX_DST, font, "  ");
  1166.     }else{
  1167.         if (monthBoxes[row][column].hasNotes) {
  1168.             pw_write(datesCrayon, 
  1169.                 column * DATE_BOX_WIDTH + DATE_BORDER + (column * GAP),
  1170.                 row * DATE_BOX_HEIGHT + DATE_BORDER + (row * GAP),
  1171.                 DATE_BOX_WIDTH, DATE_BOX_HEIGHT, PIX_SRC, 
  1172.                 hilite ? &bigDaySelPr : &bigDayPr, 
  1173.                 0, 0);
  1174.         }else{
  1175.             pw_write(datesCrayon, 
  1176.                 column * DATE_BOX_WIDTH + DATE_BORDER + (column * GAP),
  1177.                 row * DATE_BOX_HEIGHT + DATE_BORDER + (row * GAP),
  1178.                 DATE_BOX_WIDTH, DATE_BOX_HEIGHT, PIX_SRC, 
  1179.                 hilite ? &daySelPr : &dayPr, 
  1180.                 0, 0);
  1181.         }
  1182.         sprintf(dateString, "%2u", monthBoxes[row][column].date);
  1183.         pw_text(datesCrayon, 
  1184.             column * DATE_BOX_WIDTH + DATE_BORDER + (column * GAP) + 8,
  1185.             row * DATE_BOX_HEIGHT + DATE_BORDER + (row * GAP) + 20,
  1186.             PIX_SRC | PIX_DST, font, dateString);
  1187.     }
  1188.  
  1189. }
  1190.  
  1191. notesDisplay()
  1192.  
  1193.  
  1194. {
  1195.     int                     type,
  1196.                           i;
  1197.     char                 timeString[7];
  1198.     struct apptsData     *cur;
  1199.  
  1200.  
  1201.     i = (int)window_get(notesDsply, TEXTSW_LENGTH);
  1202.     if ( i > 0 ) {
  1203.         textsw_erase( notesDsply, 0, i + 1 );
  1204.     }
  1205.  
  1206.     for (type = 0; type < NUM_NOTES_TYPE; type++) {
  1207.  
  1208.         typeMark[0] = typeChar[type];
  1209.  
  1210.         cur = firstApptRecord[type];
  1211.         while ( (cur != NULL) && (cur->dateNum < dateNumToShow[type]) ) {
  1212.             cur = cur->next;                    
  1213.         }
  1214.  
  1215.         while ( (cur != NULL) && (cur->dateNum == dateNumToShow[type]) ) {
  1216.             
  1217.             textsw_insert( notesDsply, typeMark, 2 );
  1218.             if (cur->time != 0) {
  1219.                 sprintf(timeString, "%d:%02d ", 
  1220.                     (int)(cur->time / 100), (cur->time % 100));
  1221.                 textsw_insert( notesDsply, timeString, strlen(timeString) );
  1222.             }
  1223.             textsw_insert( notesDsply, cur->apptMsg, strlen(cur->apptMsg) );
  1224.             textsw_insert( notesDsply, "\n", 1 );
  1225.             cur = cur->next;                    
  1226.         }
  1227.     
  1228.     }
  1229.  
  1230.     editCount = (int)window_get(notesDsply, TEXTSW_EDIT_COUNT);
  1231.     window_set(notesDsply, TEXTSW_FIRST_LINE, 0, 0);
  1232.     window_set(notesDsply, TEXTSW_UPDATE_SCROLLBAR, 0);
  1233.  
  1234. }
  1235.  
  1236. notesSave()
  1237.  
  1238.  
  1239. {
  1240.     int                     bufLen,
  1241.                          row, column,
  1242.                          numNotes,
  1243.                          type,
  1244.                          newEditCount,
  1245.                          thisTime, thisYear, thisMonth, thisDay;
  1246.     char                *thisMsg,
  1247.                         *untypedMsg,
  1248.                         *notesBuffer;
  1249.     struct apptsData     *cur,
  1250.                         *new,
  1251.                         *old,
  1252.                         *nextAppt[NUM_NOTES_TYPE];
  1253.  
  1254.     newEditCount = (int)window_get(notesDsply, TEXTSW_EDIT_COUNT);
  1255.     if (newEditCount <= editCount) {
  1256.         return;
  1257.     }
  1258.     editCount = newEditCount;
  1259.  
  1260.     for (type = 0; type < NUM_NOTES_TYPE; type++) {
  1261.  
  1262.         cur = firstApptRecord[type];
  1263.         while ( (cur != NULL) && (cur->dateNum < dateNumToShow[type]) ) {
  1264.             cur = cur->next;                    
  1265.         }
  1266.  
  1267.         while ( (cur != NULL) && (cur->dateNum == dateNumToShow[type]) ) {
  1268.             if (cur->prev != NULL) {
  1269.                 cur->prev->next = cur->next;
  1270.             }else{
  1271.                 firstApptRecord[type] = cur->next;
  1272.             }
  1273.             if (cur->next != NULL) {
  1274.                 cur->next->prev = cur->prev;
  1275.             }else{
  1276.                 lastApptRecord[type] = cur->prev;
  1277.             }
  1278.             old = cur;        
  1279.             cur = cur->next;        
  1280.             free(old->apptMsg);
  1281.             free(old);            
  1282.         }
  1283.         nextAppt[type] = cur;
  1284.  
  1285.     }
  1286.  
  1287.     numNotes = 0;
  1288.     bufLen = (int)window_get(notesDsply, TEXTSW_LENGTH);
  1289.     
  1290.     if (bufLen > 0) {
  1291.  
  1292.         notesBuffer = (char *)malloc( bufLen + 1 );
  1293.         window_get( notesDsply, TEXTSW_CONTENTS, 0, notesBuffer, bufLen + 1 );
  1294.     
  1295.         thisMsg = strtok( notesBuffer, "\n" );
  1296.  
  1297.         while ( thisMsg != NULL ) {
  1298.     
  1299.             stripType(thisMsg, &untypedMsg, &type);
  1300.             findTime(&untypedMsg, &thisTime);
  1301.                 
  1302.             if (strlen (untypedMsg) != 0) {
  1303.  
  1304.                 thisYear = thisMonth = thisDay = 0;
  1305.                 switch (type) {
  1306.                     case NOTES_D_M_Y:
  1307.                         thisYear = yearToShow;
  1308.                     case NOTES_D_M_ALL:
  1309.                         thisMonth = monthToShow;
  1310.                     case NOTES_D_ALL_ALL:
  1311.                         thisDay = dayToShow;
  1312.                 }
  1313.  
  1314.                 new = (struct apptsData *)malloc( sizeof( struct apptsData ) );
  1315.                 new->year = thisYear;
  1316.                 new->month = thisMonth;
  1317.                 new->day = thisDay;
  1318.                 new->dateNum = dateNumToShow[type];
  1319.                 new->time = thisTime;
  1320.                 new->apptMsg = (char *)malloc( strlen(untypedMsg) + 1 );
  1321.                 strcpy( new->apptMsg, untypedMsg );
  1322.  
  1323.                 if (nextAppt[type] != NULL) {
  1324.                     new->prev = nextAppt[type]->prev;
  1325.                     if (new->prev != NULL) {
  1326.                         new->prev->next = new;
  1327.                     }else{
  1328.                         firstApptRecord[type] = new;
  1329.                     }                
  1330.                     new->next = nextAppt[type];
  1331.                     if (new->next != NULL) {
  1332.                         new->next->prev = new;
  1333.                     }else{
  1334.                         lastApptRecord[type] = new;
  1335.                     }                
  1336.                 }else{    
  1337.                     if ( lastApptRecord[type] != NULL ) {
  1338.                         new->next = NULL;
  1339.                         new->prev = lastApptRecord[type];
  1340.                         lastApptRecord[type]->next = new;
  1341.                         lastApptRecord[type] = new;
  1342.                     }else{                
  1343.                         firstApptRecord[type] = lastApptRecord[type] = new;
  1344.                         new->prev = new->next = NULL;
  1345.                     }
  1346.                 }    
  1347.     
  1348.                 if (type != NOTES_ALL_ALL_ALL) {    
  1349.                     numNotes++;
  1350.                 }
  1351.  
  1352.             }
  1353.             free(untypedMsg);
  1354.             thisMsg = strtok( NULL, "\n" );
  1355.  
  1356.         }
  1357.  
  1358.         free(notesBuffer);
  1359.  
  1360.     }
  1361.  
  1362.     for (row = 0; row < DATE_ROWS; row++) {
  1363.         for (column = 0; column < DATE_COLS; column++) {
  1364.             if (dayToShow == monthBoxes[row][column].date) {
  1365.                 if (numNotes > 0) {
  1366.                     monthBoxes[row][column].hasNotes = 1;
  1367.                 }else{
  1368.                     monthBoxes[row][column].hasNotes = 0;
  1369.                 }
  1370.                 dateBoxDisplay(row, column, HIGHLIGHT);
  1371.             }
  1372.         }
  1373.     }
  1374.     
  1375.  
  1376.     notesModified = 1; 
  1377.  
  1378. }
  1379.  
  1380. int     stripType( oldMsg, newMsg, type )
  1381.  
  1382. char         *oldMsg;
  1383. char        **newMsg;
  1384. int             *type;
  1385.  
  1386. {
  1387.     int             i,j,
  1388.                  typeFound, thisIsTypeChar;
  1389.  
  1390.     *newMsg = (char *)malloc( strlen(oldMsg) + 1 );
  1391.  
  1392.     i = 0;
  1393.     typeFound = 0;
  1394.  
  1395.     while ( *oldMsg != '\0' ) {
  1396.         thisIsTypeChar = 0;
  1397.         for (j = 0; j < NUM_NOTES_TYPE; j++) {
  1398.             if ( *oldMsg == typeChar[j] ) {
  1399.                 *type = j;
  1400.                 thisIsTypeChar = 1;
  1401.                 typeFound = 1;
  1402.             }
  1403.         }            
  1404.         if (thisIsTypeChar) {
  1405.             oldMsg++;
  1406.             while (*oldMsg == ' ') {
  1407.                 oldMsg++;
  1408.             }
  1409.         }else{
  1410.             (*newMsg)[i] = *oldMsg;
  1411.             oldMsg++;
  1412.             i++;
  1413.         }        
  1414.     } 
  1415.     (*newMsg)[i] = '\0';
  1416.  
  1417.     if ( !typeFound ) {
  1418.         *type = NOTES_D_M_Y;
  1419.     }
  1420.  
  1421. }
  1422.  
  1423. findTime(msg, time)
  1424.  
  1425. char     **msg;
  1426. int         *time;
  1427.  
  1428. {
  1429.     char     timeString[5];
  1430.     char    *curChar;
  1431.     int         timeFound;
  1432.  
  1433.     curChar = *msg;                        
  1434.     while (*curChar == ' ') {
  1435.         curChar++;
  1436.     }
  1437.  
  1438.     if (strlen(curChar) >= 4) {        
  1439.  
  1440.         timeFound = 1;
  1441.         if (*(curChar+1) == ':') {
  1442.             timeString[0] = '0';    
  1443.         }else if (*(curChar+2) == ':') {
  1444.             if (isdigit(*curChar)) {
  1445.                 timeString[0] = *curChar;
  1446.                 curChar++;
  1447.             }else{
  1448.                 timeFound = 0;
  1449.             }
  1450.         }else{
  1451.             timeFound = 0;
  1452.         }
  1453.  
  1454.         if (timeFound) {
  1455.             if ( isdigit(*curChar) && isdigit(*(curChar+2)) && isdigit(*(curChar+3)) &&
  1456.                     ( (*(curChar+4) == ' ') || (*(curChar+4) == '\0') ) ) {
  1457.                 timeString[1] = *curChar;
  1458.                 timeString[2] = *(curChar+2);
  1459.                 timeString[3] = *(curChar+3);
  1460.                 timeString[4] = '\0';                        
  1461.             }else{
  1462.                 timeFound = 0;
  1463.             }
  1464.         }
  1465.     }else{
  1466.         timeFound = 0;
  1467.     }
  1468.  
  1469.     if (timeFound) {
  1470.         *time = atoi( timeString );
  1471.         if ( ( (int)(*time / 100) >= 24 ) || ( (*time % 100 ) >= 60 ) ) {
  1472.             *time = 0;
  1473.         }else{
  1474.             curChar += 4;
  1475.             while (*curChar == ' ') {
  1476.                 curChar++;
  1477.             }
  1478.             *msg = curChar;
  1479.         }
  1480.     }else{
  1481.         *time = 0;
  1482.     }
  1483.                                          
  1484. }
  1485.  
  1486. loadData()
  1487.  
  1488.  
  1489. {
  1490.     char                 home[80];
  1491.     FILE                *fptr;
  1492.  
  1493.     char                 basedata[80];
  1494.     char                *timestr;
  1495.     char                *apptstring;
  1496.  
  1497.     int                     i;
  1498.     struct apptsData     *new;
  1499.  
  1500.     strcpy(home, getenv("HOME"));
  1501.     strcat(home, "/.monthtool");
  1502.  
  1503.     if ((fptr = fopen(home, "r")) != NULL) {
  1504.  
  1505.         for ( i = 0; i < (NUM_NOTES_TYPE + 1 /*for NOTES_ERROR*/); i++ ){
  1506.             firstApptRecord[i] = lastApptRecord[i] = NULL;
  1507.         }
  1508.  
  1509.         while ((fgets(basedata, 80, fptr) != NULL)) {
  1510.  
  1511.             basedata[strlen(basedata) - 1] = NULL;
  1512.  
  1513.             new = (struct apptsData *)malloc( sizeof( struct apptsData ) );
  1514.  
  1515.             new->month = atoi( strtok(basedata, ",") );
  1516.             new->day = atoi( strtok(NULL, ",") );
  1517.             new->year = atoi( strtok(NULL, ",") );
  1518.             new->dateNum = 10000 * new->year + 100 * new->month + new->day;
  1519.  
  1520.             timestr = strtok(NULL,","); 
  1521.             if (strcmp(timestr, "    ") == 0) {
  1522.                 new->time = 0;
  1523.             }else{
  1524.                 new->time = atoi(timestr);
  1525.             }     
  1526.  
  1527.             apptstring = strtok(NULL, "\n" );
  1528.             new->apptMsg = malloc(strlen(apptstring) + 1);
  1529.             strcpy(new->apptMsg, apptstring);
  1530.  
  1531.             if ( new->year != 0 ) {
  1532.                 if ( new->month != 0 ) {
  1533.                     if ( new->day != 0 ) {
  1534.                         i = NOTES_D_M_Y;
  1535.                     }else{
  1536.                         i = NOTES_ERROR;    /* *mmyyyy */
  1537.                     }
  1538.                 }else{
  1539.                     i = NOTES_ERROR;        /* dd*yyyy or **yyyy */
  1540.                 }
  1541.             }else{
  1542.                 if ( new->month != 0 ) {
  1543.                     if ( new->day != 0 ) {
  1544.                         i = NOTES_D_M_ALL;
  1545.                     }else{
  1546.                         i = NOTES_ERROR;    /* *mm* */
  1547.                     }
  1548.                 }else{
  1549.                     if ( new->day != 0 ) {
  1550.                         i = NOTES_D_ALL_ALL;
  1551.                     }else{
  1552.                         i = NOTES_ALL_ALL_ALL;   
  1553.                     }
  1554.                 }
  1555.             }
  1556.                 
  1557.             if ( i == NOTES_ERROR ) {
  1558.                 fprintf(stderr, "Monthtool warning! Invalid record: %u,%u,%4u,",
  1559.                     new->month, new->day, new->year );
  1560.                 if (new->time != 0) {
  1561.                     fprintf(stderr, "%04u", new->time);
  1562.                 }else{
  1563.                     fprintf(stderr, "    ");
  1564.                 }
  1565.                 fprintf(stderr, ",%s\n", new->apptMsg );
  1566.             }
  1567.  
  1568.             insertApptRecord(new, i);
  1569.                         
  1570.         }
  1571.  
  1572.         fclose(fptr);
  1573.     }
  1574.  
  1575.  
  1576. insertApptRecord(new, type)
  1577.  
  1578. struct apptsData     *new;
  1579. int                     type;
  1580.  
  1581. {
  1582.     struct apptsData     *cur;
  1583.     int                     inserted;
  1584.  
  1585.     if (lastApptRecord[type] == NULL) {
  1586.         firstApptRecord[type] = lastApptRecord[type] = new;
  1587.         new->prev = NULL;                
  1588.         new->next = NULL;    
  1589.     }else{
  1590.         inserted = 0;
  1591.         cur = lastApptRecord[type];
  1592.         do {
  1593.             if (new->dateNum >= cur->dateNum) {
  1594.                 if (cur->next != NULL) {
  1595.                     cur->next->prev = new;
  1596.                 }else{
  1597.                     lastApptRecord[type] = new;
  1598.                 }
  1599.                 new->next = cur->next;
  1600.                 new->prev = cur;
  1601.                 cur->next = new;
  1602.                 inserted = 1;
  1603.             }else{
  1604.                 cur = cur->prev;
  1605.             }
  1606.         } while ( !inserted && cur != NULL );
  1607.         if (!inserted) {
  1608.             new->next = firstApptRecord[type];
  1609.             new->prev = NULL;
  1610.             firstApptRecord[type]->prev = new;
  1611.             firstApptRecord[type] = new;
  1612.         }                        
  1613.     }
  1614.  
  1615. }
  1616.  
  1617. saveData()
  1618.  
  1619.  
  1620. {
  1621.     FILE                *fptr;
  1622.     char                 home[80];
  1623.  
  1624.     int                     i;
  1625.     struct apptsData     *cur ;
  1626.  
  1627.     notesSave();
  1628.  
  1629.     if (notesModified) {
  1630.  
  1631.         strcpy(home, getenv("HOME"));
  1632.         strcat(home, "/.monthtool");
  1633.  
  1634.         if ((fptr = fopen(home, "w")) == NULL) {
  1635.             fprintf(stderr, "Monthtool error:  Cannot open %s file", home);
  1636.             return;
  1637.         }
  1638.  
  1639.         for ( i = 0; i < (NUM_NOTES_TYPE + 1 /*for NOTES_ERROR*/); i++ ) {
  1640.             for (cur = firstApptRecord[i]; cur != NULL; cur = cur->next) {
  1641.                 fprintf(fptr, "%u,%u,%u,", cur->month, cur->day, cur->year );
  1642.                 if (cur->time != 0) {
  1643.                     fprintf(fptr, "%04u", cur->time);
  1644.                 }else{
  1645.                     fprintf(fptr, "    ");
  1646.                 }
  1647.                 fprintf(fptr, ",%s\n", cur->apptMsg );
  1648.             }
  1649.         }
  1650.  
  1651.         fclose(fptr);
  1652.  
  1653.         notesModified = 0;
  1654.  
  1655.     }
  1656.  
  1657. }
  1658.  
  1659. freeData()
  1660.  
  1661.  
  1662. {
  1663.  
  1664.     int                     i;
  1665.     struct apptsData     *cur ;
  1666.  
  1667.     for ( i = 0; i < (NUM_NOTES_TYPE + 1 /*for NOTES_ERROR*/); i++ ) {
  1668.         while( firstApptRecord[i] != NULL) {
  1669.             cur = firstApptRecord[i]; 
  1670.             firstApptRecord[i] = firstApptRecord[i]->next;
  1671.             free(cur->apptMsg);
  1672.             free( cur );
  1673.         }
  1674.     }
  1675.     
  1676. }
  1677.     
  1678. SHAR_EOF
  1679. if test -f 'monthtool.font.uu'
  1680. then
  1681.     echo shar: over-writing existing file "'monthtool.font.uu'"
  1682. fi
  1683. cat << \SHAR_EOF > 'monthtool.font.uu'
  1684. begin 666 monthtool.font
  1685. M 1X&!@ '  \                                                 
  1686. M                                                            
  1687. M                                                            
  1688. M                                                            
  1689. M                                            #PH%  < !P /  \*
  1690. M!0 '  < '@ /"@4 !P ' "T #PH%  < !P                          
  1691. M                                                            
  1692. M                     #P #PH%  < !P!+  \*!0 '  < 6@ /"@4 !P '
  1693. M &D #PH%  < !P!X  \*!0 '  < AP /"@4 !P ' )8 #PH%  < !P"E  \*
  1694. M!0 '  < M  /"@4 !P ' ,, #PH%  < !P#2  \*!0 '  < X0 /"@4 !P '
  1695. M /  #PH%  < !P#_  \*!0 '  <!#@ /"@4 !P ' 1T #PH%  < !P$L  \*
  1696. M!0 '  <!.P /"@4 !P ' 4H #PH%  < !P%9  \*!0 '  <!:  /"@4 !P '
  1697. M 7< #PH%  < !P&&  \*!0 '  <!E0 /"@4 !P ' :0 #PH%  < !P&S  \*
  1698. M!0 '  <!P@ /"@4 !P ' =$ #PH%  < !P'@  \*!0 '  <![P /"@4 !P '
  1699. M ?X #PH%  < !P(-  \*!0 '  <"'  /"@4 !P ' BL #PH%  < !P(Z  \*
  1700. M!0 '  <"20 /"@4 !P ' E@ #PH%  < !P)G  \*!0 '  <"=@ ."@0 !P '
  1701. M H0 #PH%  < !P*3  \*!0 '  <"H@ /"@4 !P ' K$ #PH%  < !P+   \*
  1702. M!0 '  <"SP /"@4 !P ' MX #PH%  < !P+M  X*!  '  <"^P /"@4 !P '
  1703. M PH #PH%  < !P,9  \*!0 '  <#*  /"@4 !P ' S< #PH%  < !P-&  \*
  1704. M!0 '  <#50 /"@4 !P ' V0 #PH%  < !P-S  \*!0 '  <#@@ /"@4 !P '
  1705. M Y$ #PH%  < !P.@  \*!0 '  <#KP /"@4 !P ' [X #PH%  < !P/-  \*
  1706. M!0 '  <#W  /"@4 !P ' ^L #PH%  < !P/Z  \*!0 '  <$"0 /"@4 !P '
  1707. M!!@ #PH%  < !P0G  \*!0 '  <$-@ /"@4 !P '!$4 #@H$  < !P13  \*
  1708. M!0 '  <$8@ /"@4 !P '!'$ #PH%  < !P2   \*!0 '  <$CP /"@4 !P '
  1709. M!)X #PH%  < !P2M  \*!0 '  <$O  /"@4 !P '!,L #PH%  < !P3:  \*
  1710. M!0 '  <$Z0 /"@4 !P '!/@ #PH%  < !P4'  \*!0 '  <%%@ /"@4 !P '
  1711. M!24 #PH%  < !P4T  \*!0 '  <%0P /"@4 !P '!5( #PH%  < !P5A  \*
  1712. M!0 '  <%<  /"@4 !P '!7\ #PH%  < !P6.  \*!0 '  <%G0 /"@4 !P '
  1713. M!:P #PH%  < !P6[  \*!0 '  <                                 
  1714. M                                                            
  1715. M                                                            
  1716. M                                                            
  1717. M              7*  \*!0 '  <%V0 /"@4 !P '!>@ #PH%  < !P7W  \*
  1718. M!0 '  <                                                     
  1719. M                                                            
  1720. M                                                            
  1721. M                                                            
  1722. M                                                            
  1723. M                                                            
  1724. M                                                            
  1725. M                                                            
  1726. M                                                            
  1727. M                                                            
  1728. M                                                            
  1729. M                                                            
  1730. M                                                            
  1731. M                                                            
  1732. M                                                            
  1733. M                                                            
  1734. M                                                            
  1735. M                                                            
  1736. M                                                            
  1737. M                                                            
  1738. M                                                            
  1739. M                                                            
  1740. M                                                            
  1741. M                                                            
  1742. M                                                            
  1743. M                                                 ! 0$! 0$   
  1744. M$        "@H*                "@H?"@H*'PH*       $! \1$ P& 1$
  1745. M>! 0     #!(2C0($"Q2$@P      !@D(! P2D1$.@        @($       
  1746. M        "! 0(" @(" 0$ @     (! 0" @(" @0$"         05#A4$   
  1747. M             ! 0?! 0                   8" @0            _@  
  1748. M                   8&         0$" @0$" @0$       #A$1$1$1$1$
  1749. M.        ! P4! 0$! 0?        #A$1 0($"!$?        #A$! 08! 1$
  1750. M.         0,%"1$?@0$#@       #P@(#@D! 1$.        !P@0%AD1$1$
  1751. M.        'Q$! @($! 0$        #A$1$0X1$1$.        #A$1$1,- 0(
  1752. M<            !@8   8&            !@8   8" @0       $"! @0" 0
  1753. M" 0           !\ 'P           ! (! (! @0($       #A$1 0($   
  1754. M$        !@D0DY24DQ (AP      ' 0*"@H1'Q$Q@       '@D)"0X)"(B
  1755. M?        #Q$0$! 0$!$.        '@D(B(B(B(D>        'XB("0\)" B
  1756. M?@       'XB("0\)" @<       /$1 0$!.1$0X        [D1$1'Q$1$3N
  1757. M        ?! 0$! 0$!!\        / @(" @(2$@P        9B0H,"@H)"1F
  1758. M        <" @(" @(")^        QD1L;%141$3&        SD1D9%143$SD
  1759. M       X9$1$1$1$3#@       !\(B(B/" @('         X1$1$1$1$1#@0
  1760. M* 8   !\(B(B/"@D)&8        \1$! . 0$1'@       #^DA 0$! 0$'P 
  1761. M      #N1$1$1$1$1#@       #N1$0H*"@0$!        #N1$145&PH*"@ 
  1762. M      #N1"@H$"@H1.X       #N1$0H*! 0$#@       !^0@0($"! 0GX 
  1763. M     #P@(" @(" @(" \      ! 0" @$! (" 0$     #P$! 0$! 0$! 0\
  1764. M       0*$0                              /X    0$ @         
  1765. M           X!#Q$1#H       # 0$!89$1$9-@            \1$! 1#@ 
  1766. M       ,! 0T3$1$3#8            X1'Q 1#@       X0$'P0$! 0?   
  1767. M         #9,1$1,- 0$.    ,! 0%AD1$1$[@       ! 0 ' 0$! 0?   
  1768. M      @( '@(" @(" @(<    & @("8D*#@D9@       ' 0$! 0$! 0?   
  1769. M         *A45%145            -AD1$1$[@           #A$1$1$.   
  1770. M         -AD1$1D6$! X        #9,1$1,- 0$#@       &PR(" @<   
  1771. M         #Q$, A$>        ! 0$'P0$! 0#            ,Q$1$1,-@  
  1772. M         .Y$*"@0$            .Y$5%0H*            &8D&!@D9@  
  1773. M         .Y$1"@H$! @\        'Q($"!$?       #! 0$!!@$! 0$ P 
  1774. M   0$! 0$! 0$! 0$! 0$!  8! 0$! ,$! 0$&       #):3           
  1775. M    _O[^_O[^_O[^_O[^    _H*"JJJ2DI*"@H+^    _H*"JKJJJJJ"@H+^
  1776. 1    _H*"LJJJJJJR@H+^    
  1777.  
  1778. end
  1779. SHAR_EOF
  1780. if test -f 'monthtool.h'
  1781. then
  1782.     echo shar: over-writing existing file "'monthtool.h'"
  1783. fi
  1784. cat << \SHAR_EOF > 'monthtool.h'
  1785. /*
  1786.      Name:        monthtool
  1787.   
  1788.     Purpose:     visual appointment calendar 
  1789.   
  1790.     Author:        Sarah Metcalfe apres Mike Essex & Rich Burridge
  1791.   
  1792.     Date:        June 24, 1987 
  1793.   
  1794.     Discussion: Displays a calendar to the screen for a given month.  
  1795.                 User may move the mouse to any day of the
  1796.                 month and view or enter appointments for that date. 
  1797.  
  1798. */
  1799.  
  1800. #include <stdio.h>
  1801. #include <ctype.h>
  1802.  
  1803. #include <suntool/sunview.h>
  1804. #include <suntool/canvas.h>
  1805. #include <suntool/panel.h>
  1806. #include <suntool/walkmenu.h>
  1807. #include <suntool/textsw.h>
  1808.  
  1809. char *sprintf() ;
  1810. char *malloc() ;
  1811. char *strcat();
  1812. char *strtok();
  1813. char *getenv();
  1814.  
  1815.  
  1816.  
  1817. #define  LARGEFONT        "/usr/lib/fonts/fixedwidthfonts/gallant.r.10"
  1818. #define  NORMALFONT        "/monthtool.font"
  1819.  
  1820.  
  1821. #define  DATE_ROWS            6            /* No of rows of dates. */
  1822. #define  DATE_COLS            7            /* No of columns of dates. */
  1823.  
  1824. #define  DATE_BOX_HEIGHT    26            /* Number of pixels for height. */
  1825. #define  DATE_BOX_WIDTH        40            /* No of pixels for width. */
  1826. #define  DATE_BORDER        5            /* No of pixels in border. */
  1827. #define  GAP                5            /* No of pixels between dates. */
  1828.  
  1829. #define  BTN_WIDTH            21            /* No of pixels in up and down buttons. */
  1830. #define  BTN_HEIGHT            19            /* No of pixels in up and down buttons. */
  1831.  
  1832.  
  1833. #define  WINDOW_WIDTH    (DATE_COLS * DATE_BOX_WIDTH) + \
  1834.                         ((DATE_COLS - 1) * GAP) + (2 * DATE_BORDER)
  1835. #define  MONTH_HEIGHT        35            
  1836. #define  DATES_HEIGHT   (DATE_ROWS * DATE_BOX_HEIGHT) + \
  1837.                         ((DATE_ROWS - 1) * GAP) + (2 * DATE_BORDER)
  1838. #define  NOTES_PANEL_HEIGHT    20            
  1839. #define  NOTES_HEIGHT        100            
  1840.  
  1841.  
  1842. #define  NUM_NOTES_TYPE        4                /* Types of records value */
  1843. #define  NOTES_D_M_Y        0                /* ddmmyyyy */
  1844. #define  NOTES_D_M_ALL        1                /* ddmm* */
  1845. #define  NOTES_D_ALL_ALL    2                /* dd** */
  1846. #define  NOTES_ALL_ALL_ALL    3                /* *** */
  1847. #define  NOTES_ERROR        NUM_NOTES_TYPE    /* *mmyy **yy dd*yy *mm* */
  1848.  
  1849.  
  1850. #define  MENU_CLOSE            1                /* Menu selection value */
  1851. #define  MENU_SAVE            2
  1852. #define  MENU_RELOAD        3
  1853. #define  MENU_QUIT            4
  1854.  
  1855. #define  HIGHLIGHT            1
  1856. #define  NOHIGHLIGHT        0
  1857.  
  1858. struct dateBox {
  1859.             int          date ;
  1860.             int            hasNotes ;
  1861. } ;
  1862.  
  1863. struct apptsData {
  1864.             int                   year ;
  1865.             int                   month ;
  1866.             int                   day ;
  1867.             int                   dateNum ;    /* 10000*year + 100*month + day */
  1868.             int                   time ;
  1869.             char                  *apptMsg ;
  1870.             struct apptsData    *next ; 
  1871.             struct apptsData    *prev ; 
  1872. } ;
  1873. SHAR_EOF
  1874. #    End of shell archive
  1875. exit 0
  1876. -- 
  1877.  
  1878. Sarah Metcalfe         decvax!utzoo!dciem!nrcaer!cognos!sarahm
  1879. Cognos Incorporated    3755 Riverside Drive, Ottawa, Ontario, CANADA  K1G 3N3
  1880.                        (613) 738-1440
  1881.  
  1882.  
  1883.